#version 420

const float PI = 3.1415926535897932;

// Interpolated values from the vertex shaders
in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirection_cameraspace;
in vec3 var_V;

// output values
out vec4 color;

// Values that stay constant for the whole mesh.
uniform sampler2D normalTexture;
uniform sampler2D refTexture;
uniform sampler2D refractionTexture;
uniform mat4 MVP;
uniform vec3 lightAmb;	// ambient color of light
uniform vec3 lightDif;	// diffuse light color
uniform vec3 lightSpec; // specular color of light
uniform vec3 LightPosition_worldspace; // light position in world space
uniform float time;
uniform vec2 ViewPortSize; // size of screen

vec3 water_normal(vec2 p)
{
	vec2 t1 = 0.02 * p + vec2(-0.004, 0.005) * time;
	vec2 t2 = 0.20 * p + vec2(-0.025, -0.04) * time;
	vec2 t3 = 1.00 * p + vec2( 0.014, 0.03) * time;
	vec2 t4 = 1.50 * p + vec2( 0.04, -0.05) * time;

	const vec3 ck = vec3(-2.0, +2.0, -2.0);
	const vec3 cd = vec3(+1.0, -1.0, +1.0);
	return normalize((texture2D(normalTexture, t1).xzy * ck + cd) +
		(texture2D(normalTexture, t2).xzy * ck + cd) +
		(texture2D(normalTexture, t3).xzy * ck + cd) +
		(texture2D(normalTexture, t4).xzy * ck + cd));
}

// calculate lightning
// impute : amb, dif and spec material color
vec3 calculateLightning( vec3 MaterialAmbiantColor, 
					     vec3 MaterialDiffuseColor, 
					     vec3 MaterialSpecularColor,
					     vec2 texCoord)
{
	float lightPower = 80000.0f;

	// Distance to the light
	float distance = length( LightPosition_worldspace - Position_worldspace );

	// Normal of the computed fragment, in camera space
	vec3 n = water_normal(texCoord);

	// Direction of the light (from the fragment to the light)
	vec3 l = normalize( LightDirection_cameraspace );

	float cosTheta = clamp( dot( n,l ), 0,1 );

	// Eye vector (towards the camera)
	vec3 E = normalize(EyeDirection_cameraspace);
	// Direction in which the triangle reflects the light
	vec3 R = reflect(-l,n);
	// Cosine of the angle between the Eye vector and the Reflect vector,
	float cosAlpha = clamp( dot( E,R ), 0,1 );

	return 	MaterialAmbiantColor + 
		   	// Diffuse : "color" of the object
			MaterialDiffuseColor * lightDif  * cosTheta +
		    // Specular : reflective highlight, like a mirror
		    MaterialSpecularColor * lightSpec * lightPower  * pow(cosAlpha,3)  / (distance*distance);
}

void main(void)
{
	vec4 t = gl_FragCoord;
	t.x = t.x / ViewPortSize.x;
	t.y = t.y / ViewPortSize.y;

	t = clamp(t, 0.0, 1.0);

	vec3 N = water_normal(gl_TexCoord[0].xy);
	t.xy = t.xy + N.xz / 10 / length(var_V);


	// Material properties
	vec3 MaterialDiffuseColor = mix(texture(refTexture, t.xy).rgb, texture(refractionTexture, t.xy).rgb, 0.7);
	vec3 MaterialAmbiantColor = vec3(0.02,0.02,0.2) * MaterialDiffuseColor;
	vec3 MaterialSpecularColor = vec3(0.3,0.3,0.3);

	color = vec4(calculateLightning(MaterialAmbiantColor,MaterialDiffuseColor, MaterialSpecularColor, UV),1.0);
}